home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
Xpm
/
pixmap
/
PortEditorP.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
20KB
|
752 lines
/*
* $Id: PortEditorP.c,v 1.2 1992/10/27 08:41:56 mallet Exp $
*
* Copyright 1992 Lionel Mallet
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appears in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Lionel MALLET not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. Lionel MALLET makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* This software is opened and free. Furthermore, everybody is kindly
* invited to participate to improve it for the benefit of all.
* Improvements can be new features, bugs fixes and porting issues
* resolution.
*
* Author: Tim Wise - Scientific & Engineering Software (SES), Inc.
*/
#include <string.h>
/*****************************************************************************/
/*
Port List Routines
A list of ports is kept in the XpmExtension format which is an
array of strings, one for each port. Convert string format
to Port structure when needed.
*/
/*****************************************************************************/
Boolean _PORTDEBUG = True;
#define XpmPortName "Ports"
#define UNKNOWN -1
typedef char PortInfo[80];
typedef struct {
int id; /* unique number */
int x; /* location of port */
int y;
char info[80]; /* port info: name, kind */
} Port;
/*--------------------------------------------------------------------------*/
/*
N e w P o r t
Allocate a new port structure including a string for info.
Return a pointer to allocated structure.
*/
/*--------------------------------------------------------------------------*/
Port *NewPort()
{
Port *p;
p = (Port *) XtNew(Port);
if (p != NULL) {
p->id = UNKNOWN;
p->x = UNKNOWN;
p->y = UNKNOWN;
/* p->info = XtMalloc( sizeof(PortInfo) ) */
p->info[0] = '\0';
}
return p;
}
/*--------------------------------------------------------------------------*/
/*
S t r T o P o r t
Convert a string to a port structure. Return a pointer to the
port structure. NOTE: Caller must free structure!!
*/
/*--------------------------------------------------------------------------*/
void StrToPort( str, p )
char *str;
Port *p;
{
char *s, *t;
if (str != NULL && p != NULL) {
sscanf( str, "%d%d%d",&p->id, &p->x, &p->y );
p->info[0] = '\0';
s = XtMalloc( strlen(str) + 1 );
strcpy( s, str );
t = strtok( s, " ," ); /* first token id */
t = strtok( NULL, " ," ); /* second token x */
t = strtok( NULL, " ," ); /* third token y */
if (t != NULL && t+strlen(t)+1 < s+strlen(str))
strcpy( p->info, t+strlen(t)+1 );/* stuff after tokens */
}
}
/*--------------------------------------------------------------------------*/
/*
P o r t T o S t r
Convert a port structure to a string. Return pointer to string.
Caller must free string.
*/
/*--------------------------------------------------------------------------*/
char *PortToStr( p )
Port *p;
{
char id_str[40];
char x_str[40];
char y_str[40];
char *str = NULL;
if (p != NULL) {
sprintf( id_str, "%d\0", p->id );
sprintf( x_str, "%d\0", p->x );
sprintf( y_str, "%d\0", p->y );
str = XtMalloc( strlen(x_str) + strlen(y_str) + strlen(id_str)
+ strlen(p->info) + 4 );
str[0] = '\0';
strcat( str, id_str );
strcat( str, " " );
strcat( str, x_str );
strcat( str, " " );
strcat( str, y_str );
strcat( str, " " );
strcat( str, p->info );
}
return str;
}
/*--------------------------------------------------------------------------*/
/*
U p d a t e P o r t
Replace string version of port i with info given in port structure.
*/
/*--------------------------------------------------------------------------*/
void UpdatePort( ports, i, p )
XpmExtension *ports;
int i;
Port *p;
{
XtFree( ports->lines[i] );
ports->lines[i] = PortToStr( p );
}
/*--------------------------------------------------------------------------*/
/*
F i n d P o r t
Search a list of ports and find the first at location (x,y).
If found, return index of port; otherwise return UNKNOWN.
*/
/*--------------------------------------------------------------------------*/
int FindPort( ports, at_x, at_y )
XpmExtension *ports;
Position at_x;
Position at_y;
{
int i;
int x;
int y;
Port p;
if (strcmp(ports->name, XpmPortName) == 0) {
for (i=0; i < ports->nlines ; i++) {
if ( StrToPort(ports->lines[i], &p)
&& p.x == at_x && p.y == at_y ) {
return i;
}
}
}
return UNKNOWN;
}
/*--------------------------------------------------------------------------*/
/*
I s P o r t
See if a port exists at location (x,y). If so, return True and
set the index of the port extension and the index of the port.
*/
/*--------------------------------------------------------------------------*/
Boolean IsPort( w, x, y, ports, port_i )
widget w;
Position x;
Position y;
XpmExtension **return_ports; /* list of ports; can be NULL! */
int *return_port_i; /* index of port x,y; can be NULL! */
{
Boolean result = False;
XpmExtension *ports;
int i;
if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) {
if ( (j=FindPort(ports, x, y)) >= 0 ) {
result = True;
}
}
if ( return_port_i != NULL )
*return_port_i = port_i;
if ( return_ports != NULL )
*return_ports = ports;
else if ( ports != NULL )
XpmFreeExtension( ports ); /* free ports if caller */
/* doesn't want them */
return result;
}
/*--------------------------------------------------------------------------*/
/*
A d d P o r t
Add a port to end of list. Return index of new port.
*/
/*--------------------------------------------------------------------------*/
int AddPort( ports, at_x, at_y )
XpmExtension *ports;
Position at_x;
Position at_y;
{
Port *p;
char *port_str;
int i = UNKNOWN;
if ((p=NewPort()) != NULL) {
p->x = at_x;
p->y = at_y;
p->id = 0; /* mark as new port */
if ( (port_str=PortToStr(p)) != NULL ) {
i = ports->nlines;
ports->nlines++;
if (ports->lines != NULL)
ports->lines = (char **) XtRealloc(
ports->lines,
ports->nlines * sizeof(char*) );
else
ports->lines = (char **) XtNew( char** );
ports->lines[i] = port_str;
}
XtFree(p);
}
return i;
}
/*--------------------------------------------------------------------------*/
/*
D e l P o r t
Delete port i. Shift array elements above i to the left.
*/
/*--------------------------------------------------------------------------*/
void DelPort( ports, i )
XpmExtension *ports;
int i;
{
char **s, **t, **last;
XtFree( ports->lines[i] );
last = ports->lines + ports->nlines; /* last element */
ports->nlines--;
/* shift left elements above deletion, if necessary */
if (ports->nlines > 0)
for (t = ports->lines+i, s = ports->lines+i+1 ; s < last ; *t++ = *s++);
else {
XtFree( ports->lines );
ports->lines = NULL;
}
}
/*--------------------------------------------------------------------------*/
/*
T r a n s l a t e P o r t
Add offsets dx and dy to location of port i.
*/
/*--------------------------------------------------------------------------*/
void TranslatePort( ports, port_i, dx, dy )
XpmExtension *ports;
int port_i;
int dx;
int dy;
{
Port p;
if ( StrToPort(ports->lines[port_i], &p) ) {
p.x += dx;
p.y += dy;
UpdatePort( ports, port_i, &p );
}
}
/*****************************************************************************/
/*
Graphics Routines to draw ports
*/
/*****************************************************************************/
/*--------------------------------------------------------------------------*/
/*
P o r t S h a p e
Return an array of points defining a port's shape.
*/
/*--------------------------------------------------------------------------*/
XPoint *PortShape(PW, x ,y)
PixmapWidget PW;
Position x;
Position y;
{
#define NPortPoints 7
static XPoint points[NPortPoints];
points[0].x = InWindowX(PW, x);
points[0].y = InWindowY(PW, y);
points[1].x = InWindowX(PW, x + 1.0/2);
points[1].y = InWindowY(PW, y + 1.0/2);
points[2].x = InWindowX(PW, x);
points[2].y = InWindowY(PW, y + 1);
points[3].x = InWindowX(PW, x + 1);
points[3].y = InWindowY(PW, y + 1);
points[4].x = InWindowX(PW, x + 1.0/2);
points[4].y = InWindowY(PW, y + 1.0/2);
points[5].x = InWindowX(PW, x + 1);
points[5].y = InWindowY(PW, y);
points[6].x = InWindowX(PW, x);
points[6].y = InWindowY(PW, y);
return points;
}
/*--------------------------------------------------------------------------*/
/*
D r a w P o r t
*/
/*--------------------------------------------------------------------------*/
#define DrawPort(w, x, y) \
XFillPolygon(XtDisplay(w), XtWindow(w), PW->pixmap.framing_gc,\
PortShape(w, x, y), NPortPoints, Convex, CoordModeOrigin)
/*--------------------------------------------------------------------------*/
/*
H i g h l i g h t P o r t
*/
/*--------------------------------------------------------------------------*/
#define HighlightPort(w, x, y)\
XFillPolygon(XtDisplay(w), XtWindow(w), PW->pixmap.highlighting_gc,\
PortShape(w, x, y), NPortPoints, Convex, CoordModeOrigin)
/*****************************************************************************/
/*
Port Editor Interface Routines
*/
/*****************************************************************************/
/*--------------------------------------------------------------------------*/
/*
D r a w P o r t
Just draw a port a location (x,y) with given value (set, clear,
invert, or highlight).
*/
/*--------------------------------------------------------------------------*/
void DrawPort( w, x, y, value )
Widget w;
Position x;
Position y;
int value;
{
if (value == Set)
DrawPort( w, x, y );
else if (value == Clear || value == Invert)
DrawPort( w, x, y );
else if (value == Highlight)
HighlightPort( w, x, y );
}
/*--------------------------------------------------------------------------*/
/*
D r a w I f P o r t
Draw a port at location (x,y) if there is a port at that
location. This routine is used to highlight a port that a
user is trying to pick.
*/
/*--------------------------------------------------------------------------*/
void DrawIfPort( w, x, y, value )
Widget w;
Position x;
Position y;
int value;
{
if ( IsPort(w, x, y, NULL, NULL) )
DrawPort( w, x, y, value );
}
/*--------------------------------------------------------------------------*/
/*
S e t P o r t
Create and draw a port at (x,y) if there is not already a port
there.
*/
/*--------------------------------------------------------------------------*/
void SetPort( w, x, y, value )
Widget w;
Position x;
Position y;
int value;
{
int ext_i, port_i;
if (_PORTDEBUG)
printf("SetPort : %d %d \n", x, y);
if ( !IsPort(w, x, y, &ext_i, &port_i) ) {
if (ext_i == UNKNOWN)
ext_i = AddExtension( &(PW->pixmap.extensions),
&(PW->pixmap.nextensions), XpmPortName );
AddPort(PW->pixmap.extensions + ext_i, x, y);
DrawPort(w, x, y, value);
if (_PORTDEBUG)
PrintExtensions(PW->pixmap.extensions, PW->pixmap.nextensions);
}
}
/*--------------------------------------------------------------------------*/
/*
C l e a r P o r t
Delete the port at (x,y) from the port list and erase the port
on the screen.
*/
/*--------------------------------------------------------------------------*/
void ClearPort(w, x, y, value)
Widget w;
Position x;
Position y;
int value;
{
int ext_i, port_i;
PixmapWidget PW = (PixmapWidget) w;
if (_PORTDEBUG)
printf("PWClearPort : %d %d \n", x, y);
if ( IsPort(PW, x, y, &ext_i, &port_i) ) {
DelPort(PW->pixmap.extensions + ext_i, port_i);
/* if no more data for this extension, delete it */
if (PW->pixmap.extensions[ext_i].nlines == 0)
DelExtension( &(PW->pixmap.extensions),
&(PW->pixmap.nextensions), ext_i );
DrawPort(w, x, y, value);
if (_PORTDEBUG)
PrintExtensions(PW->pixmap.extensions, PW->pixmap.nextensions);
}
}
/*--------------------------------------------------------------------------*/
/*
D r a g P o r t
Draw a port while the user is dragging. Draw only if a port existed
at the starting location of the drag.
*/
/*--------------------------------------------------------------------------*/
static struct {
Boolean b; /* Are we dragging? */
XPoint from; /* starting point of drag */
} dragging = { False };
void DragPort(w, x, y, value)
Widget w;
Position x;
Position y;
int value;
{
PixmapWidget PW = (PixmapWidget) w;
/* if beginning of drag, ... */
if (dragging.b == False) {
dragging.b = True;
dragging.from.x = x;
dragging.from.y = y;
}
if (IsPort(PW, dragging.from.x, dragging.from.y, NULL, NULL)) {
DrawPort( w, dragging.from.x, dragging.from.y, value );/* erase */
DrawPort( w, x, y, value );/* draw */
}
}
/*--------------------------------------------------------------------------*/
/*
M o v e P o r t
Move a port from one location to another after user has completed
dragging.
*/
/*--------------------------------------------------------------------------*/
void MovePort( w, new_x, new_y, value )
Widget w;
Position new_x;
Position new_y;
int value;
{
XpmExtension *ports;
Port p;
int i;
if ( IsPort(w, dragging.from.x, dragging.from.y, &ports, &i) &&
!IsPort(PW, new_x, new_y, NULL, NULL) ) {
DrawPort( w, dragging.from.x, dragging.from.y, value );/* erase old */
DrawPort( w, new_x, new_y, value ); /* draw new */
TranslatePort( ports, i,
new_x - dragging.from.x,
new_y - dragging.from.y );
PWUpdateExtension( w, ports );
XpmFreeExtensions( ports );
if (_PORTDEBUG)
PrintPorts( ports );
}
dragging.b = False;
}
/*--------------------------------------------------------------------------*/
/*
P o r t I n f o
Allow the user to edit the port information for the port at (x,y).
*/
/*--------------------------------------------------------------------------*/
#include "Dialog.h"
extern Dialog input_dialog;
void PortInfo( w, x, y, value )
Widget w;
Position x;
Position y;
int value;
{
XpmExtension *ports;
Port p;
int i;
char *newInfo;
if ( IsPort(w, x, y, &ports, &i) ) {
StrToPort( ports->lines[i], &p );
if ( PopupDialog( input_dialog,
"Port Info: <name> <kind>",
p.info, &newInfo,
XtGrabExclusive) == Okay ) {
strcpy( p.info, newInfo );
UpdatePort( ports, i, &p );
}
PWUpdateExtension( w, ports );
XpmFreeExtensions( ports );
if (_PORTDEBUG)
PrintPorts( ports );
}
}
/*--------------------------------------------------------------------------*/
/*
R e d r a w P o r t s
Redraw all ports of PixmapWidget.
*/
/*--------------------------------------------------------------------------*/
void RedrawPorts( w )
Widget w;
{
XpmExtension *ports;
Port p;
int i;
if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) {
for ( i=0; i < ports->nlines; i++ ) {
StrToPort( ports->lines[i], &p );
DrawPort( w, p.x, p.y );
}
}
}
/*--------------------------------------------------------------------------*/
/*
T r a n s l a t e P o r t s
For all ports in PixmapWidget, add dx,dy to the ports location.
*/
/*--------------------------------------------------------------------------*/
void TranslatePorts( PW, dx, dy )
PixmapWidget PW;
int dx;
int dy;
{
XpmExtension *ports;
Port p;
int i;
if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) {
for ( i=0; i < ports->nlines; i++ ) {
StrToPort( ports->lines[i], &p );
DrawPort( w, p.x, p.y ); /* erase old */
PWTranslatePoint( w, &p.x, &p.y, dx, dy );
DrawPort( w, p.x, p.y ); /* draw new */
UpdatePort( ports, i, &p );
}
PWUpdateExtension( w, ports );
XpmFreeExtensions( ports );
if (_PORTDEBUG)
PrintPorts( ports );
}
}
/*--------------------------------------------------------------------------*/
/*
F l i p P o r t s
Flip all ports of a PixmapWidget either horiziontally or vertically.
*/
/*--------------------------------------------------------------------------*/
void FlipPorts( w, axis )
widget w;
enum FlipAxis axis;
{
XpmExtension *ports;
Port p;
int i;
if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) {
for ( i=0; i < ports->nlines; i++ ) {
StrToPort( ports->lines[i], &p );
DrawPort( w, p.x, p.y ); /* erase old */
PWFlipPoint( w, &p.x, &p.y, axis );
DrawPort( w, p.x, p.y ); /* draw new */
UpdatePort( ports, i, &p );
}
PWUpdateExtension( w, ports );
XpmFreeExtensions( ports );
if (_PORTDEBUG)
PrintPorts( ports );
}
}
/*--------------------------------------------------------------------------*/
/*
R o t a t e P o r t s
Flip all ports of a PixmapWidget either left or right 90 degrees.
*/
/*--------------------------------------------------------------------------*/
void RotatePorts( w, direction )
widget w;
enum RotateDirection direction;
{
XpmExtension *ports;
Port p;
int i;
if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) {
for ( i=0; i < ports->nlines; i++ ) {
StrToPort( ports->lines[i], &p );
DrawPort( w, p.x, p.y ); /* erase old */
PWRotatePoint( w, &p.x, &p.y, direction );
DrawPort( w, p.x, p.y ); /* draw new */
UpdatePort( ports, i, &p );
}
PWUpdateExtension( w, ports );
XpmFreeExtensions( ports );
if (_PORTDEBUG)
PrintPorts( ports );
}
}